package com.rickpan.controller;

import com.rickpan.dto.common.ApiResponse;
import com.rickpan.dto.request.LoginRequest;
import com.rickpan.dto.request.RegisterRequest;
import com.rickpan.dto.request.SendResetCodeRequest;
import com.rickpan.dto.request.VerifyResetCodeRequest;
import com.rickpan.dto.request.ResetPasswordRequest;
import com.rickpan.dto.response.LoginResponse;
import com.rickpan.dto.response.UserResponse;
import com.rickpan.entity.User;
import com.rickpan.repository.UserRepository;
import com.rickpan.security.UserDetailsServiceImpl;
import com.rickpan.service.AuthService;
import com.rickpan.service.PasswordResetService;
import com.rickpan.utils.AliOssUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;

/**
 * 认证控制器
 */
@Tag(name = "认证管理", description = "用户认证相关接口")
@RestController
@RequestMapping("/api/auth")
public class AuthController {

    private static final Logger logger = LoggerFactory.getLogger(AuthController.class);

    @Autowired
    private AuthService authService;

    @Autowired
    private PasswordResetService passwordResetService;

    @Autowired
    private UserRepository userRepository;

    /**
     * 用户注册
     */
    @PostMapping("/register")
    public ApiResponse<UserResponse> register(@Valid @RequestBody RegisterRequest request) {
        logger.info("用户注册请求: {}", request.getUsername());
        UserResponse user = authService.register(request);
        return ApiResponse.success("注册成功", user);
    }

    /**
     * 用户登录
     */
    @PostMapping("/login")
    public ApiResponse<LoginResponse> login(@Valid @RequestBody LoginRequest request) {
        logger.info("用户登录请求: {}", request.getUsername());
        LoginResponse response = authService.login(request);
        return ApiResponse.success("登录成功", response);
    }

    /**
     * 获取当前用户信息
     */
    @GetMapping("/me")
    public ApiResponse<UserResponse> getCurrentUser(@AuthenticationPrincipal UserDetailsServiceImpl.UserPrincipal userPrincipal) {
        logger.info("获取当前用户信息: {}", userPrincipal.getId());
        UserResponse user = authService.getCurrentUser(userPrincipal.getId());
        return ApiResponse.success(user);
    }

    /**
     * 刷新Token
     */
    @PostMapping("/refresh")
    public ApiResponse<Map<String, String>> refreshToken(@RequestHeader("Authorization") String authHeader) {
        logger.info("刷新Token请求");
        
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            return ApiResponse.badRequest("无效的Authorization头");
        }
        
        String token = authHeader.substring(7);
        String newToken = authService.refreshToken(token);
        
        Map<String, String> response = new HashMap<>();
        response.put("token", newToken);
        
        return ApiResponse.success("Token刷新成功", response);
    }

    /**
     * 用户登出
     */
    @PostMapping("/logout")
    public ApiResponse<String> logout(@AuthenticationPrincipal UserDetailsServiceImpl.UserPrincipal userPrincipal) {
        Long userId = userPrincipal != null ? userPrincipal.getId() : null;
        logger.info("用户登出请求: userId={}", userId);
        authService.logout(userId);
        return ApiResponse.success("登出成功");
    }

    /**
     * 设置用户在线状态
     */
    @PostMapping("/set-online")
    public ApiResponse<String> setUserOnline(@RequestBody Map<String, Object> request,
                                           @AuthenticationPrincipal UserDetailsServiceImpl.UserPrincipal userPrincipal) {
        try {
            Long userId = userPrincipal.getId();
            String sessionId = (String) request.get("sessionId");
            @SuppressWarnings("unchecked")
            Map<String, Object> clientInfo = (Map<String, Object>) request.get("clientInfo");

            logger.info("设置用户在线状态请求: userId={}, sessionId={}", userId, sessionId);
            authService.setUserOnline(userId, sessionId, clientInfo);
            return ApiResponse.success("在线状态设置成功");
        } catch (Exception e) {
            logger.error("设置用户在线状态失败", e);
            return ApiResponse.error("设置在线状态失败");
        }
    }

    /**
     * 检查用户名是否可用
     */
    @GetMapping("/check-username")
    public ApiResponse<Map<String, Boolean>> checkUsername(@RequestParam String username) {
        boolean available = authService.isUsernameAvailable(username);
        Map<String, Boolean> response = new HashMap<>();
        response.put("available", available);
        return ApiResponse.success(response);
    }

    /**
     * 检查邮箱是否可用
     */
    @GetMapping("/check-email")
    public ApiResponse<Map<String, Boolean>> checkEmail(@RequestParam String email) {
        boolean available = authService.isEmailAvailable(email);
        Map<String, Boolean> response = new HashMap<>();
        response.put("available", available);
        return ApiResponse.success(response);
    }

    /**
     * 发送密码重置验证码
     */
    @PostMapping("/send-reset-code")
    @Operation(summary = "发送密码重置验证码", description = "向用户邮箱发送密码重置验证码")
    public ApiResponse<String> sendResetCode(@Valid @RequestBody SendResetCodeRequest request) {
        logger.info("发送密码重置验证码请求: {}", request.getEmail());
        try {
            passwordResetService.sendResetCode(request.getEmail());
            return ApiResponse.success("验证码已发送，请查收邮件");
        } catch (Exception e) {
            logger.error("发送密码重置验证码失败: {}", request.getEmail(), e);
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 验证密码重置验证码
     */
    @PostMapping("/verify-reset-code")
    @Operation(summary = "验证密码重置验证码", description = "验证用户输入的密码重置验证码")
    public ApiResponse<String> verifyResetCode(@Valid @RequestBody VerifyResetCodeRequest request) {
        logger.info("验证密码重置验证码请求: {}", request.getEmail());
        try {
            passwordResetService.verifyResetCode(request.getEmail(), request.getCode());
            return ApiResponse.success("验证码验证成功");
        } catch (Exception e) {
            logger.error("验证密码重置验证码失败: {}", request.getEmail(), e);
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 重置密码
     */
    @PostMapping("/reset-password")
    @Operation(summary = "重置密码", description = "使用验证码重置用户密码")
    public ApiResponse<String> resetPassword(@Valid @RequestBody ResetPasswordRequest request) {
        logger.info("重置密码请求: {}", request.getEmail());
        try {
            passwordResetService.resetPassword(request.getEmail(), request.getCode(), request.getPassword());
            return ApiResponse.success("密码重置成功");
        } catch (Exception e) {
            logger.error("重置密码失败: {}", request.getEmail(), e);
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 上传用户头像
     */
    @PostMapping("/profile/avatar")
    @Operation(summary = "上传用户头像", description = "上传用户头像到阿里云OSS")
    @SecurityRequirement(name = "bearerAuth")
    public ApiResponse<String> uploadAvatar(
            @Parameter(description = "头像文件") @RequestParam("file") MultipartFile file,
            @AuthenticationPrincipal UserDetailsServiceImpl.UserPrincipal userDetails) {

        logger.info("用户 {} 上传头像", userDetails.getUsername());

        try {
            // 验证文件
            if (file.isEmpty()) {
                return ApiResponse.error("文件不能为空");
            }

            // 验证文件类型
            String contentType = file.getContentType();
            if (contentType == null || !contentType.startsWith("image/")) {
                return ApiResponse.error("只支持图片文件");
            }

            // 验证文件大小 (2MB)
            if (file.getSize() > 2 * 1024 * 1024) {
                return ApiResponse.error("文件大小不能超过2MB");
            }

            // 生成文件名
            String objectName = AliOssUtil.generateAvatarObjectName(userDetails.getId(), file.getOriginalFilename());

            // 上传到OSS
            String avatarUrl = AliOssUtil.uploadFile(objectName, file.getInputStream());

            // 更新用户头像URL
            User user = userRepository.findById(userDetails.getId())
                    .orElseThrow(() -> new RuntimeException("用户不存在"));
            user.setAvatarUrl(avatarUrl);
            userRepository.save(user);

            logger.info("用户 {} 头像上传成功: {}", userDetails.getUsername(), avatarUrl);
            return ApiResponse.success(avatarUrl);

        } catch (Exception e) {
            logger.error("用户 {} 头像上传失败", userDetails.getUsername(), e);
            return ApiResponse.error("头像上传失败: " + e.getMessage());
        }
    }

    /**
     * 健康检查
     */
    @GetMapping("/health")
    public ApiResponse<Map<String, String>> health() {
        Map<String, String> response = new HashMap<>();
        response.put("status", "UP");
        response.put("service", "RickPan Auth Service");
        return ApiResponse.success(response);
    }
}
